package com.weixing.mall.core.support;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.imagesearch20201214.Client;
import com.aliyun.imagesearch20201214.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.weixing.mall.core.properties.WeiXingProperties;
import com.weixing.mall.core.properties.ali.ImgProperties;
import com.weixing.mall.core.properties.ali.OssProperties;
import com.weixing.mall.core.support.imgsearch.ImgSearchAddDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * @program: mall-master
 * @description: 图片服务
 * @author: wangfang
 * @create: 2021-10-25 16:18
 **/
public class ImageService {

   

    /***
     * 获取图片客户端
     * @return
     * @throws Exception
     */
    public Client getCilent(ImgProperties properties) throws Exception {
        Config authConfig = new Config();
        authConfig.accessKeyId = properties.getAccessKeyId();
        authConfig.accessKeySecret = properties.getAccessKeySecret();
        authConfig.endpoint = properties.getEndpoint();
        authConfig.regionId = properties.getRegionId();
        return new Client(authConfig);
    }

    /**
     * 获取新增图片请求的链接
     *
     * @return
     * @throws Exception
     */
    public AddImageAdvanceRequest getAddRequest(ImgProperties properties) throws Exception {
        AddImageAdvanceRequest request = new AddImageAdvanceRequest();
        // 必填，图像搜索实例名称。
      request.instanceName = properties.getInstanceName();
        return request;
    }

    /**
     * 获取新增图片请求的链接
     *
     * @return
     * @throws Exception
     */
    public SearchImageByPicAdvanceRequest getSerchRequest(Integer categoryId, Integer pageSize,ImgProperties properties) throws Exception {
        SearchImageByPicAdvanceRequest request = new SearchImageByPicAdvanceRequest();
        // 必填，图像搜索实例名称。
       request.instanceName = properties.getInstanceName();
        // 选填，商品类目。
        // 1. 对于商品搜索：若设置类目，则以设置的为准；若不设置类目，将由系统进行类目预测，预测的类目结果可在Response中获取 。
        // 2. 对于布料、商标、通用搜索：不论是否设置类目，系统会将类目设置为88888888。
        if (ObjectUtil.isNotNull(categoryId)) {
            request.categoryId = categoryId;
        }
        // 选填，返回结果的数目。取值范围：1-100。默认值：10。
        request.num = 10;
        // 选填，返回结果的起始位置。取值范围：0-499。默认值：0。
        request.start = pageSize*10;
        // 选填，是否需要进行主体识别，默认为true。
        // 1.为true时，由系统进行主体识别，以识别的主体进行搜索，主体识别结果可在Response中获取。
        // 2. 为false时，则不进行主体识别，以整张图进行搜索。
        // 3.对于布料图片搜索，此参数会被忽略，系统会以整张图进行搜索。
        request.crop = true;
        return request;
    }

    /**
     * 获取网络图片输入流
     *
     * @param url
     * @return
     */
    public InputStream getStream(String url) {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setReadTimeout(5000);
            connection.setConnectTimeout(5000);
            connection.setRequestMethod("GET");
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                return inputStream;
            }
        } catch (IOException e) {
            System.out.println("图片路径获取异常，图片地址为：" + url);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 新增图片搜索引擎
     *
     * @param imgSearchAddDtos 图片列表，包括图片的ID和图片名称是必须项
     * @throws Exception
     */
    public boolean add(List<ImgSearchAddDto> imgSearchAddDtos,ImgProperties properties) throws Exception {
        Client client = getCilent(properties);
        boolean result=true;
        AddImageAdvanceRequest request = getAddRequest(properties);
        for (ImgSearchAddDto dto : imgSearchAddDtos) {
            System.out.println(dto.getPicName()+"开始上传！");
            // 必填，商品id，最多支持 512个字符。
            // 一个商品可有多张图片。
            request.productId = dto.getProductId();
            // 必填，图片名称，最多支持 512个字符。
            // 1. ProductId + PicName唯一确定一张图片。
            // 2. 如果多次添加图片具有相同的ProductId + PicName，以最后一次添加为准，前面添加的图片将被覆盖。
            request.picName = dto.getPicName();
            // 选填，图片类目。
            // 1. 对于商品搜索：若设置类目，则以设置的为准；若不设置类目，将由系统进行类目预测，预测的类目结果可在Response中获取 。
            // 2. 对于布料、商标、通用搜索：不论是否设置类目，系统会将类目设置为88888888。
            request.categoryId = dto.getCategoryId();
            // 选填，用户自定义的内容，最多支持4096个字符。
            // 查询时会返回该字段。例如可添加图片的描述等文本。
            request.customContent = dto.getCustomContent();
            // 选填，整数类型属性，可用于查询时过滤，查询时会返回该字段。
            //  例如不同的站点的图片/不同用户的图片，可以设置不同的IntAttr，查询时通过过滤来达到隔离的目的
            request.intAttr = dto.getIntAttr();
            // 选填，字符串类型属性，最多支持 128个字符。可用于查询时过滤，查询时会返回该字段。
            request.strAttr = dto.getStrAttr();
            // 选填，是否需要进行主体识别，默认为true。
            // 1.为true时，由系统进行主体识别，以识别的主体进行搜索，主体识别结果可在Response中获取。
            // 2. 为false时，则不进行主体识别，以整张图进行搜索。
            // 3.对于布料图片搜索，此参数会被忽略，系统会以整张图进行搜索。
            request.crop = dto.getCrop();
            // 选填，图片的主体区域，格式为 x1,x2,y1,y2, 其中 x1,y1 是左上角的点，x2，y2是右下角的点。设置的region 区域不要超过图片的边界。
            // 若用户设置了Region，则不论Crop参数为何值，都将以用户输入Region进行搜索。
            // 对于布料图片搜索，此参数会被忽略，系统会以整张图进行搜索。
            //request.region = "167,467,221,407";
            RuntimeOptions runtimeOptions = new RuntimeOptions();
            String picName = dto.getImgUrl();
            InputStream inputStream = getStream(picName);
            // 图片内容，最多支持 4MB大小图片以及5s的传输等待时间。当前仅支持PNG、JPG、JPEG、BMP、GIF、WEBP、TIFF、PPM格式图片；
            // 对于商品、商标、通用图片搜索，图片长和宽的像素必须都大于等于100且小于等于4096；
            // 对于布料搜索，图片长和宽的像素必须都大于等于448且小于等于4096；
            // 图像中不能带有旋转信息
            request.picContentObject = inputStream;
            try {
                AddImageResponse response = client.addImageAdvance(request, runtimeOptions);
                System.out.println("success: " + response.getBody().success + ". message: "
                        + response.getBody().message        + ". categoryId: "
                        + response.getBody().picInfo.categoryId + ". region:"
                        + response.getBody().picInfo.region
                        + ". requestId: " + response.getBody().requestId);
                System.out.println(dto.getPicName()+"上传成功");
            } catch (TeaException e) {
                result=false;
                System.out.println(e.getCode());
                System.out.println(e.getData());
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
        return  result;
    }

    /**
     * 图片搜索服务，根据上传的图片获取商品列表
     * @param file
     * @return
     */
    public List<SearchImageByPicResponseBody.SearchImageByPicResponseBodyAuctions> search(MultipartFile file, Integer pageSize,ImgProperties properties) {
        try {
            Client client = getCilent(properties);
            SearchImageByPicAdvanceRequest request = getSerchRequest(null,null==pageSize?0:pageSize,properties);
            request.picContentObject = file.getInputStream();
            RuntimeOptions runtimeObject = new RuntimeOptions();
            SearchImageByPicResponse response = client.searchImageByPicAdvance(request, runtimeObject);
            System.out.println(response.getBody().requestId);
            System.out.println(response.getBody().picInfo.categoryId);
            System.out.println(response.getBody().picInfo.region);
            List<SearchImageByPicResponseBody.SearchImageByPicResponseBodyAuctions> auctions = response.getBody().getAuctions();
            for (SearchImageByPicResponseBody.SearchImageByPicResponseBodyAuctions auction : auctions) {
                System.out.println(auction.categoryId + " " + auction.picName + " "
                        + auction.productId + " " + auction.customContent + " " + auction.score + " "
                        + auction.strAttr + " " + auction.intAttr);
            }
            System.out.println("多主体信息");
            SearchImageByPicResponseBody.SearchImageByPicResponseBodyPicInfo picInfo = response.getBody().getPicInfo();
            for (SearchImageByPicResponseBody.SearchImageByPicResponseBodyPicInfoMultiRegion multiRegion : picInfo.getMultiRegion()) {
                System.out.println(multiRegion.region);
            }
            return auctions;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
